package com.xbongbong.crm.perform.command.delete;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.abstracts.AbstractCrmDeleteService;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.elasticsearch.model.PaasFormDataEsModel;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.FormDataDeleteBatchVO;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.parent.pojo.delete.ErrorDataPojo;
import com.xbongbong.pro.contact.pojo.vo.ContactDeleteBatchVO;
import com.xbongbong.pro.contactuser.pojo.dto.ContactUserDeleteBatchDTO;
import com.xbongbong.pro.enums.errorcodes.BuinessDefaultErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author sunshaoxiang
 * @ClassName ContactDeleteServiceImpl
 * @Description 联系人 batch delete 业务层
 * @Date 2022/5/23 9:25
 * @Version 1.0
 **/
@Service("contactDeleteServiceImpl")
public class ContactDeleteServiceImpl extends AbstractCrmDeleteService<PaasFormEntityExt, ContactEntityExt> {

    public static final Logger LOGGER = LoggerFactory.getLogger(ContactDeleteServiceImpl.class);

    @Resource
    private ContactModel contactModel;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private PaasFormDataEsModel paasFormDataEsModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    public List<Integer> businessType() {
        return Collections.singletonList(XbbRefTypeEnum.CONTACT.getCode());
    }

    @Override
    public FormDataDeleteBatchVO deleteWorkflow(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        List<Long> contactIdIn = formDataDeleteBatchDTO.getDataIdList();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        contactModel.deleteBatch(contactIdIn, corpid);
        contactUserModel.deleteBatchByContactIdIn(contactIdIn, corpid);
        return new FormDataDeleteBatchVO();
    }

    @Override
    public FormDataDeleteBatchVO deleteBatchNoPermission(FormDataDeleteBatchDTO formDataDeleteBatchDTO, PaasFormEntityExt form) throws XbbException {
        List<ContactEntityExt> list = deleteEsData(formDataDeleteBatchDTO, formDataDeleteBatchDTO.getDataIdList(), formDataDeleteBatchDTO.getCorpid());
        List<Long> deleteIdIn = deleteData(formDataDeleteBatchDTO, formDataDeleteBatchDTO.getDataIdList(), list, formDataDeleteBatchDTO.getCorpid());
        ErrorDataPojo errorDataPojo = new ErrorDataPojo();
        errorDataPojo.setDeleteList(deleteIdIn);
        log(formDataDeleteBatchDTO, list, errorDataPojo);
        return new FormDataDeleteBatchVO(new ArrayList<>(), new ArrayList<>(), "", deleteIdIn);
    }

    @Override
    public List<ContactEntityExt> deleteEsData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> dataIdIn, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", dataIdIn);
        param.put("del", DelEnum.NORMAL.getDel());
        List<ContactEntityExt> list = contactModel.findEntitys(param);
        if (Objects.isNull(list)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        //兼容删除脏数据
        if (!Objects.equals(dataIdIn.size(), list.size())) {
            list = paasEsModel.getByIdList(dataIdIn, corpid, null, IndexTypeEnum.IDX_SAAS_CONTACT, ContactEntityExt.class);
        }
        return list;
    }

    @Override
    public ErrorDataPojo notAllowData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<ContactEntityExt> list) throws XbbException {
        //联系人这里没有看到不允许删除的数据
        return new ErrorDataPojo();
    }

    @Override
    public List<Long> deleteData(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<Long> contactIdIn, List<ContactEntityExt> contactList, String corpid) throws XbbException {
        ContactDeleteBatchVO contactDeleteBatchVO = new ContactDeleteBatchVO();
        try {

            PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByBusinessType(RedundantTemplateTypeEnum.CONTACT.getCode(), corpid);
            if (Objects.isNull(paasFormExplainEntity)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            String explains = paasFormExplainEntity.getExplains();
            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
            // TODO 列表循环校验删除权限
            // 删除联系人
            if (!contactIdIn.isEmpty()) {
                if (BasicConstant.ONE.equals(formDataDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(contactIdIn.size())) {
                    contactModel.deleteByKey(contactIdIn.get(0), corpid);
                } else {
                    contactModel.deleteBatch(contactIdIn, corpid);
                }
                contactDeleteBatchVO.setDeleteIds(contactIdIn);
            }
            // 删除联系人关系
            ContactUserDeleteBatchDTO contactUserDeleteBatchDTO = new ContactUserDeleteBatchDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO, contactUserDeleteBatchDTO);
            contactUserDeleteBatchDTO.setContactIdIn(contactIdIn);
            contactUserModel.deleteBatchByContactIdIn(contactIdIn, corpid);

            Set<Long> customerIds = new HashSet<>();
            PaasFormDataEntityExt formData;
            for (ContactEntityExt entityExt : contactList) {
                formData = contactModel.getByKey(entityExt.getId(), corpid);
                if (formData == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
                }
                if (FlowStatusEnum.inApproval(formData.getFlowStatus()) && (Objects.isNull(formDataDeleteBatchDTO.getIsBusinessRule()) || Objects.equals(0, formDataDeleteBatchDTO.getIsBusinessRule()))) {
                    // 【联系人】编辑进审批的联系人，不应该允许在客户详情页中删除
                    // 是在客户详情的联系人人为删除需要校验是否进审批
                    throw new XbbException(BuinessDefaultErrorCodeEnum.API_ERROR_200020);
                }
                JSONObject data = entityExt.getData();
                Long customerId = data.getLong(ContactEnum.CUSTOMER_NAME.getAttr());
                customerIds.add(customerId);
            }
            for (long customerId : customerIds) {
                Map<String, String> sortMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                sortMap.put("field", ContactEnum.IS_MAIN.getAttr());
                sortMap.put("sort", SortOrder.DESC.toString());
                PaasFormDataEsListVO paasFormDataEsListVO = getEsListVoByLinkIdAndCondition(formDataDeleteBatchDTO, customerId, ContactEnum.CUSTOMER_NAME.getAttr(), XbbRefTypeEnum.CONTACT.getCode(), new ArrayList<>(), sortMap, explainMap);
                List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();
                // 判断删除联系人关联的客户是否只剩下一个联系人（bug:17151 客户只有1个联系人时，联系人默认为客户的主联系人）
                // List<ContactUserEntity> contactUserList = contactUserModel.getListByCustomerId(corpid, contactDeleteBatchDTO.getUserId(), customerId);
                if (paasFormDataESList.size() == 1) {
                    Long contactId = paasFormDataESList.get(0).getDataId();
                    ContactEntityExt contactEntityExt = contactModel.getByKey(contactId, corpid);
                    JSONObject contactEntityExtData = contactEntityExt.getData();
                    contactEntityExtData.put(ContactEnum.IS_MAIN.getAttr(), BasicConstant.ONE);
                    contactModel.update(contactEntityExt);
                }
            }
        }catch (XbbException e){
            throw e;
        }catch (Exception e) {
            LOGGER.error("ContactDeleteServiceImpl.deleteData 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return contactIdIn;
    }

    @Override
    public void log(FormDataDeleteBatchDTO formDataDeleteBatchDTO, List<ContactEntityExt> contactList, ErrorDataPojo errorDataPojo) throws XbbException {
        //查询名称
        List<String> contactName= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(ContactEntityExt entityExt : contactList){
            JSONObject data = entityExt.getData();
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, ContactEnum.NAME.getAttr(), "");
            contactName.add(name);
        }
        String corpid = formDataDeleteBatchDTO.getCorpid();
        List<Long> idIn = errorDataPojo.getDeleteList();
        OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
        if (Objects.equals(1, formDataDeleteBatchDTO.getIsBusinessRule())) {
            operateTypeEnum = OperateTypeEnum.RULE_DELETE;
        }
        //生成删除日志(区分单个删除和批量删除)
        String userId = formDataDeleteBatchDTO.getUserId();
        String userName = formDataDeleteBatchDTO.getLoginUserName();
        String nameStr = StringUtils.join(contactName, "，");
        if(idIn.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.CONTACT.getName(), idIn.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(ContactEnum.NAME.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CONTACT, operateTypeEnum,
                    "", "", memo, formDataDeleteBatchDTO.getHttpHeader());
        } else if (Objects.equals(idIn.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.CONTACT.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CONTACT, operateTypeEnum,
                    idIn.get(0).toString(), nameStr, memo, formDataDeleteBatchDTO.getHttpHeader());
        }
    }

    @Override
    public void deleteAfter(List<Long> dataIdList, FormDataDeleteBatchDTO formDataDeleteBatchDTO, PaasFormEntityExt form) throws XbbException {
        lowCodeExecuteService(dataIdList, form.getSaasMark(), form.getBusinessType(), form.getId(), formDataDeleteBatchDTO.getCorpid());
        // 工作流，业务规则
        startWorkflow(formDataDeleteBatchDTO, form.getBusinessRules(), dataIdList);
    }

    @Override
    public void rollback(List<Long> list, String corpid) {

    }


    /**
     * 根据关联id和条件获取数据
     *对应重构前 -> com.xbongbong.saas.service.impl.ContactServiceImpl#getEsListVoByLinkIdAndCondition(com.xbongbong.pro.contact.pojo.dto.ContactDeleteBatchDTO, java.lang.Long, java.lang.String, java.lang.Integer, java.util.List, java.util.Map, java.util.Map)
     * @param formDataDeleteBatchDTO 入参
     * @param linkId              关联id
     * @return 数据
     * @throws XbbException 异常
     */
    private PaasFormDataEsListVO getEsListVoByLinkIdAndCondition(FormDataDeleteBatchDTO formDataDeleteBatchDTO, Long linkId, String attr, Integer businessType, List<ConditionsEntityExt> conditions, Map<String, String> sortMap, Map<String, FieldAttrEntity> explainMap) throws XbbException {
        PaasFormDataEsListVO paasFormDataEsListVO;
        FormDataListDTO formDataListDTO = new FormDataListDTO();
        BeanUtil.copyProperties(formDataDeleteBatchDTO, formDataListDTO);
        formDataListDTO.setAppId(null);
        formDataListDTO.setFormId(null);
        ConditionsEntityExt conditionsEntityExt = new ConditionsEntityExt();
        conditionsEntityExt.setAttr(attr);
        conditionsEntityExt.setSymbol(ConditionEnum.EQUAL.getSymbol());
        conditionsEntityExt.setValue(Collections.singletonList(linkId));
        conditionsEntityExt.setFieldType(FieldTypeEnum.TEXT.getType());
        conditions.add(conditionsEntityExt);
        formDataListDTO.setDel(DelEnum.NORMAL.getDel());
        formDataListDTO.setConditions(conditions);
        formDataListDTO.setBusinessType(businessType);
        formDataListDTO.setSortMap(sortMap);
        formDataListDTO.setExplainMap(explainMap);
        formDataListDTO.setSearchSubForm(false);
        IndexTypeEnum indexTypeEnum = indexTypeModel.getIndexType(formDataListDTO.getCorpid(), formDataListDTO.getBusinessType(), formDataListDTO.getSaasMark());
        paasFormDataEsListVO = paasFormDataEsModel.list(formDataListDTO, indexTypeEnum);
        return paasFormDataEsListVO;
    }

}
